#pragma once
#include <vector>
#include <assert.h>
using namespace std;

template <class tType>
class Tab2D{
	unsigned int _w;
	unsigned int _h;
	vector<tType> _tab;

public:
	Tab2D():
			_w(0),
			_h(0){
		_tab.clear();
	}

	Tab2D(int aW, int aH):
			_w(aW),
			_h(aH){
		_tab.assign(_w*_h, NULL);
	}

	Tab2D(int aW, int aH, tType iV):
			_w(aW),
			_h(aH){
		_tab.assign(_w*_h,iV);
	}

	Tab2D(const Tab2D& aTab):
			_tab(aTab._tab),
			_w(aTab._w),
			_h(aTab._h){
	}

	void build(int aW, int aH){
		_tab.clear();
		_w = aW;
		_h = aH;
		_tab.assign(_w*_h,NULL);
	}

	void build(int aW, int aH, tType iV){
		_tab.clear();
		_w = aW;
		_h = aH;
		_tab.assign(_w*_h,iV);
	}

	bool IsLegal(unsigned int aX, unsigned int aY)
	{
		if(aX < _w && aX >= 0 && aY < _h && aY >= 0) return true;
		else return false;
	}

	tType& operator()(unsigned int aX, unsigned int aY){
		if(IsLegal(aX,aY)) return _tab[aY * _w + aX];
		else{
			assert(false);
			return _tab[0];
		}
	}

	tType& operator[](unsigned int aX){
		if(aX < _tab.size()) return _tab[aX];
		else{
			assert(false);
			return _tab[0];
		}
	}

	int getSizeW(){ return _w;}
	int getSizeH(){ return _h;}
	int getSize(){ return _w*_h;}

	void reset(){ _tab.assign(_w*_h, NULL);}
	void reset(tType iV){ _tab.assign(_w*_h,iV);}

	void move(int aX, int aY){
		if(aX >= 0){
			for(unsigned int i=0; i<_w-aX; i++){
				if(aY >= 0){
					for(unsigned int j=0; j<_h-aY; j++){
						operator()(i,j) = operator()(i+aX,j+aY);
					}
				}
				else{
					for(unsigned int j=_h-1; j>=aY; j--){
						operator()(i,j) = operator()(i+aX,j-aY);
					}
				}
			}
		}
		else{
			for(unsigned int i=_w-1; i>=aX; i--){
				if(aY >= 0){
					for(unsigned int j=0; j<_h-aY; j++){
						operator()(i,j) = operator()(i+aX,j+aY);
					}
				}
				else{
					for(unsigned int j=_h-1; j>=aY; j--){
						operator()(i,j) = operator()(i+aX,j-aY);
					}
				}
			}
		}
	}

	void print(){
		fprintf(stderr, "\nTab2D: %dx%d\n  ", _w,_h);
		for(unsigned int j=0; j<_h; j++){
			for(unsigned int i=0; i<_w; i++){
				fprintf(stderr, "%d ", operator()(i,j));
			}
			fprintf(stderr, "\n  ");
		}
		fprintf(stderr, "\n");
	}

	~Tab2D(){};
};

